package com.ngkj.zmfptes.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.google.gson.Gson;
import com.ngkj.zmfptes.bean.RentalResponseEntity;
import com.ngkj.zmfptes.service.RentalInfoService;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.ContextLoader;

import javax.annotation.Resource;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author ChenHN
 * @since 2021/11/3 creation
 **/
@Slf4j
@Service
public class RentalInfoServiceImpl implements RentalInfoService {

    @Resource
    private RestHighLevelClient restHighLevelClient;

    private static String IndexName = "ng_rental_info";

    private static Gson gson = new Gson();

    @Override
    public Boolean insertAndUpdateRental(String jsonString) {
        List<RentalResponseEntity> rentalResponseEntities = JSONArray.parseArray(jsonString, RentalResponseEntity.class);
        try {
            for (RentalResponseEntity rentalResponseEntity : rentalResponseEntities) {
                GetRequest request = new GetRequest(IndexName, Long.toString(rentalResponseEntity.getCzfxxlsh()));
                request.fetchSourceContext(new FetchSourceContext(false));
                request.storedFields("_none_");
                boolean b = restHighLevelClient.exists(request, RequestOptions.DEFAULT);
                //存在执行更新方法
                if (!b){
                    rentalResponseEntity.setQywzid(rentalResponseEntity.getQywzid().split(";")[1]);
                    BulkRequest bulkRequest = new BulkRequest();
                    bulkRequest.timeout("2m");
                    bulkRequest.add(new IndexRequest(IndexName).id(Long.toString(rentalResponseEntity.getCzfxxlsh())).source(gson.toJson(rentalResponseEntity),XContentType.JSON));
                    BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
                }else{
                    rentalResponseEntity.setQywzid(rentalResponseEntity.getQywzid().split(";")[1]);
                    UpdateRequest request1 = new UpdateRequest(IndexName, Long.toString(rentalResponseEntity.getCzfxxlsh()));
                    UpdateRequest doc = request1.doc(gson.toJson(rentalResponseEntity), XContentType.JSON);
                    UpdateResponse update = restHighLevelClient.update(request1, RequestOptions.DEFAULT);
                }
            }
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

    }
//    可匹配多个字段
//    searchSourceBuilder.query(QueryBuilders.multiMatchQuery("Spring开发框架", "name", "description").minimumShouldMatch("70%"));

    /**
     * 查询房源信息
     * @param rentalInfo 条件
     * @param pageNo 页数
     * @param pageSize 每页条数
     * @return
     * @throws IOException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    @Override
    public Map<String,Object> searchRentalInfos(RentalResponseEntity rentalInfo , int pageNo, int pageSize) throws IOException, InvocationTargetException, IllegalAccessException {
        if (pageNo < 1) {
            pageNo = 1;
        }
        //条件搜索
        SearchRequest searchRequest = new SearchRequest(IndexName);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        searchSourceBuilder.trackTotalHits(true);
        searchSourceBuilder.from((pageNo-1)*pageSize);
        searchSourceBuilder.size(pageSize);
        //精准匹配
        //组合查询
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        if (!StringUtils.isEmpty(rentalInfo.getQywzid())&& !"null".equals(rentalInfo.getQywzid())) {
            //查询区域位置
            queryBuilder.must(QueryBuilders.termQuery("qywzid",rentalInfo.getQywzid()));
        }
//        对应多字段
        if (!ObjectUtils.isEmpty(rentalInfo.getSqxx())&&!StringUtils.isEmpty(rentalInfo.getSqxx().getSqmc())&& !"null".equals(rentalInfo.getSqxx().getSqmc())) {
            queryBuilder.must(QueryBuilders.multiMatchQuery(rentalInfo.getSqxx().getSqmc(),"sqxx.sqmc","xqxx.xqmc"));
        }
        //通过审批
        queryBuilder.must(QueryBuilders.termQuery("sfsp",rentalInfo.getSfsp()));

        searchSourceBuilder.query(queryBuilder);
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        //执行搜索
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        //解析结果
        List<Map<String,Object>> list = new ArrayList<>();
        for (SearchHit documentFields : searchResponse.getHits().getHits()) {
//            RentalResponseEntity rentalInfo1 = new RentalResponseEntity();
//            BeanUtils.populate(rentalInfo1,documentFields.getSourceAsMap());
            list.add(documentFields.getSourceAsMap());
        }
        long value = searchResponse.getHits().getTotalHits().value;
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("data",list);
        map.put("total",value);
        return map;
    }

}























